﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;

public static class SerializeTool {

    static StringBuilder _text = new StringBuilder(1024);
    static string[] splitStr1 = new string[] { "|+|" };
    static string[] splitStr2 = new string[] { "|-|" };
    #region Dictonary
    static public string DictToString<TKey, TValue>(Dictionary<TKey, TValue> dict, string sp1 = null, string sp2 = null)
    {
        Debugger.Assert(dict != null, "dict must not be null");
        string s_p1;
        string s_p2;

        if (string.IsNullOrEmpty(sp1) || string.IsNullOrEmpty(sp2))
        {
            s_p1 = splitStr1[0];
            s_p2 = splitStr2[0];
        }
        else
        {
            s_p1 = sp1;
            s_p2 = sp2;
        }

        if (dict == null)
            return null;

        if (dict.Count == 0)
            return string.Empty;

        _text.Length = 0;
        foreach (var kv in dict)
        {
            _text.Append(kv.Key);
            _text.Append(s_p1);
            _text.Append(kv.Value);
            _text.Append(s_p2);
        }

        return _text.ToString();
    }

    static public Dictionary<string, string> ParseToDict_s_s(string str, string sp1 = null, string sp2 = null)
    {
        if (string.IsNullOrEmpty(sp1) || string.IsNullOrEmpty(sp2))
            return ParseToDict<string, string>(str, _parse_str, _parse_str, splitStr1, splitStr2);
        else
            return ParseToDict<string, string>(str, _parse_str, _parse_str, new string[] { sp1 }, new string[] { sp2 });
    }

    static public Dictionary<int, int> ParseToDict_i_i(string str, string sp1 = null, string sp2 = null)
    {
        if (string.IsNullOrEmpty(sp1) || string.IsNullOrEmpty(sp2))
            return ParseToDict<int, int>(str, _parse_int, _parse_int, splitStr1, splitStr2);
        else
            return ParseToDict<int, int>(str, _parse_int, _parse_int, new string[] { sp1 }, new string[] { sp2 });
    }

    static Dictionary<TKey, TValue> ParseToDict<TKey, TValue>(string str,
        System.Func<string, TKey> keyParse, System.Func<string, TValue> valParse, string[] sp1, string[] sp2)
    {
        if (string.IsNullOrEmpty(str))
            return null;

        string[] kvs = str.Split(sp2, System.StringSplitOptions.RemoveEmptyEntries);
        bool avalid = (kvs != null && kvs.Length != 0);
        Debugger.Assert(avalid, "error str : " + str);

        if (!avalid)
            return null;

        Dictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>();

        for (int i = 0; i < kvs.Length; i++)
        {
            string[] kv = kvs[i].Split(sp1, System.StringSplitOptions.RemoveEmptyEntries);
            bool avalidSplit = (kv != null && kv.Length == 2);
            Debugger.Assert(avalidSplit, "error split : " + kvs[i]);

            if (!avalidSplit)
                continue;

            TKey key = keyParse(kv[0]);
            TValue value = valParse(kv[1]);
            ret.Add(key, value);
        }

        return ret;
    }
    #endregion

    #region List
    static public string ListToString<T>(List<T> list, string split = null)
    {
        if (list == null || list.Count == 0) return string.Empty;
        _text.Length = 0;

        string sp = string.IsNullOrEmpty(split) ? splitStr1[0] : split;

        for(int i = 0; i < list.Count;i++)
        {
            _text.Append(list[i].ToString());
            _text.Append(sp);
        }

        return _text.ToString();
    }

    static public string ListToString<T>(T[] list, int count = 0, string split = null)
    {
        if (list == null || list.Length == 0) return string.Empty;
        _text.Length = 0;

        string sp = string.IsNullOrEmpty(split) ? splitStr1[0] : split;

        int size = count == 0 ? list.Length : Mathf.Min(count, list.Length);

        for (int i = 0; i < size; i++)
        {
            _text.Append(list[i].ToString());
            _text.Append(sp);
        }

        return _text.ToString();
    }

    static public T[] ParseToArr<T>(System.Func<string, T> parse, string str, string split = ",")
    {
        if (string.IsNullOrEmpty(str)) return null;
        string[] strs = str.Split(new string[] {split}, System.StringSplitOptions.RemoveEmptyEntries);
        if (strs == null || strs.Length == 0) return null;
        T[] result = new T[strs.Length];
        for (int i = 0; i < result.Length; i++)
            result[i] = parse(strs[i]);
        return result;
    }

    static public string CollectionToString<T>(IEnumerable<T> collection, string split = ",")
    {
        if (collection == null) return string.Empty;
        string sp = string.IsNullOrEmpty(split) ? splitStr1[0] : split;
        _text.Length = 0;
        foreach(T item in collection)
        {
            _text.Append(item.ToString());
            _text.Append(sp);
        }
        string res = _text.ToString();
        _text.Length = 0;
        return res;
    }

    #endregion

    static int _parse_int(string str) { return int.Parse(str); }

    static string _parse_str(string str) { return str; }
}

